package main

import (
	"encoding/json"
	"fmt"
)

// Monster 定义一个结构体
type Monster struct {
	Name string `json:"monster_name"` //反射机制
	Age  int    `json:"monster_age"`
}

// testStruct 对结构体的序列化操作
func testStruct() {
	monster := Monster{
		Name: "牛魔王",
		Age:  500,
	}
	// 序列化
	data, err := json.Marshal(&monster)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("序列化结果：", string(data))
}

// testMap 对Map的序列化操作
func testMap() {
	var a map[string]interface{}
	a = make(map[string]interface{})
	a["name"] = "红孩儿"
	a["age"] = "300"
	// 序列化
	data, err := json.Marshal(a)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("序列化结果：", string(data))

}

// testSlice 对切片的序列化操作
func testSlice() {
	var slice []map[string]interface{}
	var m1 map[string]interface{}
	// make 操作
	m1 = make(map[string]interface{})
	m1["name"] = "jack"
	m1["age"] = "20"
	slice = append(slice, m1)
	var m2 map[string]interface{}
	// make 操作
	m2 = make(map[string]interface{})
	m2["name"] = "tom"
	m2["age"] = "22"
	m2["address"] = [2]string{"广东", "上海"}
	slice = append(slice, m2)

	// 序列化
	data, err := json.Marshal(slice)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("序列化结果：", string(data))

}

// 反序列化
// unmarshalStruct 反序列化成struct
func unmarshalStruct() {
	// 定义一串json字符串，符合以上结构体
	str := `{"monster_name":"牛魔王","monster_age":500}`
	// 实例化结构体
	var monster Monster
	// 需要引用传递，将其变量改变
	err := json.Unmarshal([]byte(str), &monster)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("反序列化后的monster：", monster)
}

// unmarshalMap 反序列化成map
// 注意：反序列化map不需要make，因为make操作被封装到json.Unmarshal([]byte(str), &a)函数中，
// 原因是利用类型断言推导出来
func unmarshalMap() {
	str := `{"age":"300","name":"红孩儿"}`
	// 定义一个map
	var a map[string]interface{}
	// 进行反序列化
	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("反序列化后的a：", a)
}

// unmarshalSlice 反序列化切片
func unmarshalSlice() {
	str := `[{"age":"20","name":"jack"},{"address":["广东","上海"],"age":"22","name":"tom"}]`
	// 定义一个slice切片
	var slice []map[string]interface{}
	// 进行反序列化
	err := json.Unmarshal([]byte(str), &slice)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("反序列化后的slice：", slice)

}

func main() {
	testStruct()
	testMap()
	testSlice()

	// 反序列化
	unmarshalStruct()
	unmarshalMap()
	unmarshalSlice()
}
